SeabornUtil = {}

--- 判断是否在主要阶段
---@param phase number @ 阶段
---@return boolean
function SeabornUtil.isMainPhase(phase)
  return phase > Player.Start and phase < Player.Finish
end

--- 获取一名角色的议事结果
---@param player ServerPlayer @ 角色
---@param data DiscussionDataSpec @ 议事数据
---@return table<string, integer>? @ 意见、意见牌
function SeabornUtil.getDiscussionOpinion(player, data)
  local result = data.results[player]
  if result then
    return {result.opinion, result.toCards[1]}
  end
  return nil
end

--- 令一名角色调整手牌数
---@param player ServerPlayer @ 角色
---@param num number @ 数
---@param skill_name string @ 技能名
function SeabornUtil.adjustHand(player, num, skill_name)
  local h = player:getHandcardNum()
  if num > h then
    player:drawCards(num - h, skill_name)
  elseif num < h then
    player.room:askToDiscard(player, {
      skill_name = skill_name,
      min_num = h - num,
      max_num = h - num,
      cancelable = false,
      include_equip = false,
    })
  end
end

--- 超链接
local href_table = {
  ["调离"] = ":iberia__lure_tiger_description",
  ["合法目标数"] = ":iberia__able_targets_num",
  ["主要阶段"] = ":iberia__main_phase",
}

Fk:loadTranslationTable{
  [":iberia__lure_tiger_description"] = "调离：不计入座次、不能使用牌、防止受到伤害、防止失去体力、防止回复体力",
  [":iberia__able_targets_num"] = "合法目标数：你使用此牌时，可以被你指定为目标的角色数",
  [":iberia__main_phase"] = "主要阶段：判定阶段、摸牌阶段、出牌阶段、弃牌阶段的合集",
}

--- 创建超链接
---@param text string
---@return string
SeabornUtil.href = function(text)
  return string.format("<a href='%s' style='color:grey;'>%s</a>", href_table[text], text)
end

--- 幻化之战

--- 构建技能池
---@param room Room @ 房间
function SeabornUtil.createSkillPool(room)
  local skill_pool = {}
  local ban_types = { Skill.Limited, Skill.Wake, Skill.Quest, Skill.Lord }
  for _, g_name in ipairs(room.general_pile) do
    local general = Fk.generals[g_name]
    table.insertTableIfNeed(skill_pool, table.filter(general:getSkillNameList(), function(s)
      return not table.find(ban_types, function (t) return Fk.skills[s]:hasTag(t) end)
    end))
  end
  room:setTag("huanhua_skill_pool", skill_pool)
end

--- 获取指定数量的技能
---@param room Room @ 房间
---@param num integer? @ 数量（默认1个）
---@return string[] @ 获取到的技能
function SeabornUtil.getSkills(room, num)
  num = num or 1
  local skill_pool = room:getTag("huanhua_skill_pool")
  if num > #skill_pool then return {} end

  local skills = {}
  for _ = 1, num do
    local skill = table.random(skill_pool)
    table.removeOne(skill_pool, skill)
    table.insert(skills, skill)
  end

  return skills
end

--- 将技能塞回技能池
---@param room Room @ 房间
---@param skills string[] @ 技能
function SeabornUtil.returnToSkillPool(room, skills)
  local skill_pool = room:getTag("huanhua_skill_pool")
  table.insertTable(skill_pool, skills)
  room:setTag("huanhua_skill_pool", skill_pool)
end

--- 进行幻化
---@param room Room  @ 所在房间
function SeabornUtil.doHuanhua(room)
  local num = #room.alive_players * 3
  local skill_names = SeabornUtil.getSkills(room, num)

  if #skill_names == 0 then room:gameOver("") end
  local req = Request:new(room.alive_players, "AskForChoice")
  req.focus_text = "huanhua_choice"
  req.receive_decode = false

  for i, p in ipairs(room.alive_players) do
    local choices = {}
    local sliced_skills = table.slice(skill_names, (i-1)*3 + 1, i*3 + 1)
    table.insertTableIfNeed(choices, sliced_skills)
    table.insert(choices, "DrawTwo")

    local request_data = { choices, choices, "huanhua_choice", "#huanhua-choose", true }
    req:setData(p, request_data)
    req:setDefaultReply(p, "DrawTwo")
  end

  local selected_skills = {}
  for _, p in ipairs(room.alive_players) do
    local selected = req:getResult(p)
    if selected == "DrawTwo" then
      p:drawCards(2)
    else
      room:handleAddLoseSkills(p, selected)
      table.insert(selected_skills, selected)
    end
  end
  SeabornUtil.returnToSkillPool(room, table.filter(skill_names, function(s)
    return not table.contains(selected_skills, s)
  end))
end

-- 获知一名角色的灵力数
---@param player Player @ 角色
---@return integer @ 灵力数
function SeabornUtil.getSpiritualPower(player)
  return player:getMark("@!spiritualPower")
end

-- 修改一名角色的灵力数
---@param player ServerPlayer @ 角色
---@param num integer @ 数量
function SeabornUtil.addSiritualPower(player, num)
  if num > 0 then
    player.room:addPlayerMark(player, "@!spiritualPower", num)
  else
    player.room:removePlayerMark(player, "@!spiritualPower", -num)
  end
end

-- 获知一名角色的聚灵技能
---@param player Player @ 角色
---@return string[] @ 聚灵技能
function SeabornUtil.getJulingSkills(player)
  return player:getTableMark( "JulingSkills")
end

-- 设置一名角色的聚灵技能
---@param player ServerPlayer
---@param skill string
function SeabornUtil.setJulingSkill(player, skill)
  local room = player.room
  local juling_skills = SeabornUtil.getJulingSkills(player)
  if #juling_skills == 3 then
    local to_lose = room:askToChoice(player, {
      choices = juling_skills,
      skill_name = "spiritualPower&",
      prompt = "#JulingLose",
      detailed = true,
      cancelable = false,
    })
    table.removeOne(juling_skills, to_lose)
    room:handleAddLoseSkills(player, "-"..to_lose)
  end

  room:handleAddLoseSkills(player, skill)
  table.insert(juling_skills, skill)
  room:setPlayerMark(player, "JulingSkills", juling_skills)
  local translate = table.map(juling_skills, function(s) return Fk:translate(s) end)
  room:setPlayerMark(player, "@JulingSkills", "<font color='gold'>" .. table.concat(translate, " ") .. "</font>")
end

Fk:loadTranslationTable{
  ["huanhua_skill_pool"] = "幻化技能池",
  ["huanhua_choice"] = "幻化",

  ["DrawTwo"] = "摸两张牌",
  [":DrawTwo"] = "不要了，过牌才是硬道理！",
  ["JulingSkills"] = "聚灵",
  ["@JulingSkills"] = "",

  ["#huanhua-choose"] = "幻化：选择以下一个技能获得",
  ["#JulingLose"] = "聚灵：技能数量超出限制，选择以下1个已有的技能失去",
}

return SeabornUtil